package com.meiyuetao.myt.sale.entity;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import lab.s2jh.auth.entity.Department;
import lab.s2jh.auth.entity.User;
import lab.s2jh.bpm.BpmTrackable;
import lab.s2jh.core.annotation.MetaData;
import lab.s2jh.core.entity.annotation.SkipParamBind;
import lab.s2jh.core.web.json.DateJsonSerializer;
import lab.s2jh.core.web.json.DateTimeJsonSerializer;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.meiyuetao.myt.core.constant.VoucherStateEnum;
import com.meiyuetao.myt.core.entity.MytBaseEntity;
import com.meiyuetao.myt.customer.entity.CustomerProfile;
import com.meiyuetao.myt.finance.entity.AccountSubject;

@MetaData("退货单")
@Entity
@Table(name = "myt_sale_return")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class SaleReturn extends MytBaseEntity implements BpmTrackable {
    private static final long serialVersionUID = 1L;
    @MetaData("唯一凭证号")
    private String voucher;
    @MetaData("凭证日期")
    private Date voucherDate;
    @MetaData("凭证状态")
    private VoucherStateEnum voucherState = VoucherStateEnum.DRAFT;
    @MetaData("经办人")
    private User voucherUser;
    @MetaData("经办部门")
    private Department voucherDepartment;

    @MetaData(value = "参考来源", comments = "如填写京东，淘宝，天猫、美月淘、哎呦盒子等标识采购来源的信息")
    private String referenceSource;
    @MetaData(value = "参考凭证号", comments = "如京东，淘宝，天猫、美月淘、哎呦盒子等订单号等")
    private String referenceVoucher;

    @MetaData("备注信息")
    private String memo;

    private List<SaleReturnDetail> saleReturnDetails = new ArrayList<SaleReturnDetail>();
    @MetaData("商品售额")
    private BigDecimal totalSaleAmount;

    @MetaData("补偿客户的运费")
    private BigDecimal deliveryAmount;

    @MetaData("应退金额")
    private BigDecimal totalReturnAmount;

    @MetaData("商品总成本")
    private BigDecimal totalCommodityAmount;

    @MetaData("损耗额")
    private BigDecimal totalLossAmount;

    @MetaData("入库成本")
    private BigDecimal totalCostAmount;

    @MetaData(value = "收款会计科目")
    private AccountSubject accountSubject;
    @MetaData(value = "付款参考信息", comments = "一般用于记录其他三方系统付款的凭证信息")
    private String paymentReference;
    @MetaData("客户")
    private CustomerProfile customerProfile;

    @MetaData("提交时间")
    private Date submitDate;

    @MetaData(value = "最近操作摘要")
    private String lastOperationSummary;
    @MetaData(value = "流程当前任务节点")
    private String activeTaskName;
    @MetaData("审核时间")
    private Date auditDate;
    @MetaData("类型")
    private SaleReturnTypeEnum saleReturnType = SaleReturnTypeEnum.RTN;

    public enum SaleReturnTypeEnum {
        @MetaData("退货")
        RTN, @MetaData("换货")
        CHG, @MetaData("返修")
        REP;

    }

    // 快照 客户收货信息
    @MetaData("收货人")
    private String receivePerson;
    @MetaData("电话")
    private String mobilePhone;
    @MetaData("邮编")
    private String postCode;
    @MetaData("地址")
    private String deliveryAddr;

    @Column(length = 128, nullable = false, unique = true, updatable = false)
    @JsonProperty
    public String getVoucher() {
        return voucher;
    }

    @JsonProperty
    public BigDecimal getDeliveryAmount() {
        return deliveryAmount;
    }

    public void setDeliveryAmount(BigDecimal deliveryAmount) {
        this.deliveryAmount = deliveryAmount;
    }

    public void setVoucher(String voucher) {
        this.voucher = voucher;
    }

    @JsonProperty
    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    @Column(nullable = false)
    @JsonProperty
    @JsonSerialize(using = DateJsonSerializer.class)
    public Date getVoucherDate() {
        return voucherDate;
    }

    public void setVoucherDate(Date voucherDate) {
        this.voucherDate = voucherDate;
    }

    @Column(precision = 18, scale = 2, nullable = true)
    public BigDecimal getTotalCostAmount() {
        return totalCostAmount;
    }

    public void setTotalCostAmount(BigDecimal totalCostAmount) {
        this.totalCostAmount = totalCostAmount;
    }

    @OneToOne
    @JoinColumn(name = "customer_profile_sid", nullable = false)
    @JsonProperty
    public CustomerProfile getCustomerProfile() {
        return customerProfile;
    }

    public void setCustomerProfile(CustomerProfile customerProfile) {
        this.customerProfile = customerProfile;
    }

    @Enumerated(EnumType.STRING)
    @Column(length = 8, nullable = true)
    @JsonProperty
    public VoucherStateEnum getVoucherState() {
        return voucherState;
    }

    @SkipParamBind
    public void setVoucherState(VoucherStateEnum voucherState) {
        this.voucherState = voucherState;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "voucher_user_id", nullable = false)
    @JsonProperty
    public User getVoucherUser() {
        return voucherUser;
    }

    public void setVoucherUser(User voucherUser) {
        this.voucherUser = voucherUser;
    }

    @ManyToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "voucher_department_id", nullable = false)
    @JsonProperty
    public Department getVoucherDepartment() {
        return voucherDepartment;
    }

    public void setVoucherDepartment(Department voucherDepartment) {
        this.voucherDepartment = voucherDepartment;
    }

    @JsonProperty
    public String getReferenceSource() {
        return referenceSource;
    }

    public void setReferenceSource(String referenceSource) {
        this.referenceSource = referenceSource;
    }

    @JsonProperty
    public String getReferenceVoucher() {
        return referenceVoucher;
    }

    public void setReferenceVoucher(String referenceVoucher) {
        this.referenceVoucher = referenceVoucher;
    }

    @Lob
    @JsonIgnore
    public String getPaymentReference() {
        return paymentReference;
    }

    public void setPaymentReference(String paymentReference) {
        this.paymentReference = paymentReference;
    }

    @ManyToOne
    @JoinColumn(name = "account_subject_id")
    public AccountSubject getAccountSubject() {
        return accountSubject;
    }

    public void setAccountSubject(AccountSubject accountSubject) {
        this.accountSubject = accountSubject;
    }

    @OneToMany(mappedBy = "saleReturn", cascade = CascadeType.ALL, orphanRemoval = true)
    public List<SaleReturnDetail> getSaleReturnDetails() {
        return saleReturnDetails;
    }

    public void setSaleReturnDetails(List<SaleReturnDetail> saleReturnDetails) {
        this.saleReturnDetails = saleReturnDetails;
    }

    @JsonProperty
    @JsonSerialize(using = DateJsonSerializer.class)
    public Date getSubmitDate() {
        return submitDate;
    }

    public void setSubmitDate(Date submitDate) {
        this.submitDate = submitDate;
    }

    public BigDecimal getTotalCommodityAmount() {
        return totalCommodityAmount;
    }

    public void setTotalCommodityAmount(BigDecimal totalCommodityAmount) {
        this.totalCommodityAmount = totalCommodityAmount;
    }

    public BigDecimal getTotalLossAmount() {
        return totalLossAmount;
    }

    public void setTotalLossAmount(BigDecimal totalLossAmount) {
        this.totalLossAmount = totalLossAmount;
    }

    @JsonProperty
    public BigDecimal getTotalSaleAmount() {
        return totalSaleAmount;
    }

    public void setTotalSaleAmount(BigDecimal totalSaleAmount) {
        this.totalSaleAmount = totalSaleAmount;
    }

    @JsonProperty
    public BigDecimal getTotalReturnAmount() {
        return totalReturnAmount;
    }

    public void setTotalReturnAmount(BigDecimal totalReturnAmount) {
        this.totalReturnAmount = totalReturnAmount;
    }

    @JsonProperty
    public String getLastOperationSummary() {
        return lastOperationSummary;
    }

    public void setLastOperationSummary(String lastOperationSummary) {
        this.lastOperationSummary = lastOperationSummary;
    }

    @Override
    @Transient
    @JsonIgnore
    public String getBpmBusinessKey() {
        return voucher;
    }

    @JsonProperty
    public String getActiveTaskName() {
        return activeTaskName;
    }

    public void setActiveTaskName(String activeTaskName) {
        this.activeTaskName = activeTaskName;
    }

    @JsonProperty
    @JsonSerialize(using = DateTimeJsonSerializer.class)
    public Date getAuditDate() {
        return auditDate;
    }

    @SkipParamBind
    public void setAuditDate(Date auditDate) {
        this.auditDate = auditDate;
    }

    @Enumerated(EnumType.STRING)
    @Column(length = 8, nullable = true)
    @JsonProperty
    public SaleReturnTypeEnum getSaleReturnType() {
        return saleReturnType;
    }

    public void setSaleReturnType(SaleReturnTypeEnum saleReturnType) {
        this.saleReturnType = saleReturnType;
    }

    @JsonProperty
    public String getReceivePerson() {
        return receivePerson;
    }

    public void setReceivePerson(String receivePerson) {
        this.receivePerson = receivePerson;
    }

    @JsonProperty
    public String getMobilePhone() {
        return mobilePhone;
    }

    public void setMobilePhone(String mobilePhone) {
        this.mobilePhone = mobilePhone;
    }

    @JsonProperty
    public String getPostCode() {
        return postCode;
    }

    public void setPostCode(String postCode) {
        this.postCode = postCode;
    }

    @JsonProperty
    public String getDeliveryAddr() {
        return deliveryAddr;
    }

    public void setDeliveryAddr(String deliveryAddr) {
        this.deliveryAddr = deliveryAddr;
    }

    @Transient
    @Override
    public String getExtraInfo() {
        return null;
    }

}